"""
Case Type   : 共享存储-系统内部工具-dsscmd
Case Name   : dsscmd工具新建目录之-U UDS:socket_domain参数验证和执行节点验证
Create At   : 2023/4/13
Owner       : opentestcase019
Description :
    1.创建文件，文件正常命名
    2.创建文件，文件名包含特殊字符和路径不以+开头
    3.创建文件，文件为已存在的文件名
    4.创建文件，文件命名长度大于64
    5.创建文件，文件命名长度等于64
    6.创建文件，文件命名长度等于63
    7.创建文件，文件命名包含中文
    8.创建文件，文件命名为纯数字
    9.创建文件，文件命名为纯字母
    10.创建文件，指定-U UDS:socket_domain参数为正常值
    11.创建文件，指定错误的-U UDS:socket_domain参数
    12.创建文件，指定权限不足的socket_domain
    13.在备机执行创建文件
    14.在集群停止的情况下执行
    15.在dss关闭的情况下执行
Expect      :
    1.创建成功
    2.合理报错
    3.合理报错
    4.合理报错
    5.合理报错
    6.创建成功
    7.合理报错
    8.创建成功
    9.创建成功
    10.创建成功
    11.合理报错Failed to get uds connection.
    12.合理报错Failed to get uds connection.
    13.创建成功
    14.合理报错
    15.合理报错
History     :
"""
import os
import time
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class ShareStorageTool(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.standby_node = Node('Standby1DbUser')
        self.common = Common()
        self.constant = Constant()
        self.file_name_1 = "file_dsscmd_0021_1"
        self.file_name_2 = "file_dsscmd_0021_2"
        self.file_name_3 = "file_dsscmd_0021_3"
        self.file_name_4 = "file_dsscmd_0021_4"
        self.file_name_5 = "file_dsscmd_0021_5"
        self.file_name_65chars = \
            "file_dsscmd_0021_file_dsscmd_0021_file_dsscmd_0021_file_d_65chars"
        self.file_name_64chars = \
            "file_dsscmd_0021_file_dsscmd_0021_file_dsscmd_0021_file__64chars"
        self.file_name_63chars = \
            "file_dsscmd_0021_file_dsscmd_0021_file_dsscmd_0021_file_63chars"
        self.file_name_numbers = "0021"
        self.file_name_letters = "filedsscmd"
        self.logger.info("-----获取卷组名-----")
        execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd lsvg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn("Succeed to display lsvg info.", execute_msg, "获取卷组名失败")
        self.vgname = execute_msg.splitlines()[1].split()[0].strip()
        self.logger.info(self.vgname)
        self.path_1 = os.path.join(self.vgname, self.file_name_1)
        self.path_2 = os.path.join(self.vgname, self.file_name_2)
        self.path_3 = os.path.join(self.vgname, self.file_name_3)
        self.path_4 = os.path.join(self.vgname, self.file_name_4)
        self.path_5 = os.path.join(self.vgname, self.file_name_5)
        self.path_65chars = os.path.join(self.vgname, self.file_name_65chars)
        self.path_64chars = os.path.join(self.vgname, self.file_name_64chars)
        self.path_63chars = os.path.join(self.vgname, self.file_name_63chars)
        self.path_numbers = os.path.join(self.vgname, self.file_name_numbers)
        self.path_letters = os.path.join(self.vgname, self.file_name_letters)

    def test_sharestorage_tool(self):
        step1 = "-----step1:创建文件，文件正常命名;expect:创建成功-----"
        self.logger.info(step1)
        cmd_list = [f'+{self.path_1}', f'+{self.path_2}$3',
                    f'+{self.path_3}$q', f'+{self.path_3}$#']
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd touch -p {cmd}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.standby_node,
                                                    execute_cmd)
            self.assertIn(f"Succeed to create file",
                          execute_msg, "执行失败" + step1)

        step2 = "-----step2:创建文件，文件名包含特殊字符和路径不以+开头;" \
                "expect:合理报错-----"
        self.logger.info(step2)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_1}#;" \
            f"dsscmd touch -p +{self.path_1}%;" \
            f"dsscmd touch -p +{self.path_1}$;" \
            f"dsscmd touch -p {self.path_1}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn("decode error , path should be [0~9,a~z,A~Z,-,_,/,.].",
                      execute_msg, "执行失败" + step2)

        step3 = "-----step3:创建文件，文件为已存在的文件名;expect:合理报错-----"
        self.logger.info(step3)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_1}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Make dir or Create file failed, {self.file_name_1} "
                      f"has already existed", execute_msg, "执行失败" + step3)

        step4 = "-----step4:创建文件，文件命名长度大于64;expect:合理报错-----"
        self.logger.info(step4)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_65chars}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Path {self.file_name_65chars} decode error "
                      f"name length should less than 64.",
                      execute_msg, "执行失败" + step4)

        step5 = "-----step5:创建文件，文件命名长度等于64;expect:合理报错-----"
        self.logger.info(step5)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_65chars}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Path {self.file_name_65chars} decode error "
                      f"name length should less than 64.",
                      execute_msg, "执行失败" + step5)

        step6 = "-----step6:创建文件，文件命名长度等于63;expect:创建成功-----"
        self.logger.info(step6)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_63chars}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to create file, name is +{self.path_63chars}.",
                      execute_msg, "执行失败" + step6)

        step7 = "-----step7:创建文件，文件命名包含中文;expect:合理报错-----"
        self.logger.info(step7)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_1}文件"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"cmd touch error:2193 Path {self.path_1}文件 "
                      f"decode error , path should be [0~9,a~z,A~Z,-,_,/,.].",
                      execute_msg, "执行失败" + step7)

        step8 = "-----step8:创建文件，文件命名为纯数字;expect:创建成功-----"
        self.logger.info(step8)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_numbers}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to create file, name is +{self.path_numbers}.",
                      execute_msg, "执行失败" + step8)

        step9 = "-----step9:创建文件，文件命名为纯字母;expect:创建成功-----"
        self.logger.info(step9)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_letters}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to create file, name is +{self.path_letters}.",
                      execute_msg, "执行失败" + step9)

        step10 = "-----step10:创建文件，指定-U UDS:socket_domain参数为正常值;" \
                 "expect:创建成功-----"
        self.logger.info(step10)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_4} -U {macro.UDS_PATH}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to create file, name is +{self.path_4}.",
                      execute_msg, "执行失败" + step10)

        step11 = "-----step11:创建文件，指定错误的-U UDS:socket_domain参数;" \
                 "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step11)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_4} -U {macro.UDS_PATH}.cfg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step11)

        step12 = "-----step12:创建文件，指定权限不足的socket_domain;" \
                 "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step12)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"chmod 000 {macro.UDS_PATH[4::]};ls -l {macro.UDS_PATH[4::]};" \
            f"dsscmd touch -p +{self.path_4} -U {macro.UDS_PATH};" \
            f"chmod 600 {macro.UDS_PATH[4::]};ls -l {macro.UDS_PATH[4::]};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step12)

        step13 = "-----step13:在备机执行创建文件;expect:创建成功-----"
        self.logger.info(step13)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_5}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertIn(f"Succeed to create file, name is +{self.path_5}.",
                      execute_msg, "执行失败" + step13)

        step14 = "-----step14:在集群停止的情况下执行;expect:合理报错-----"
        self.logger.info(step14)
        stop_msg = Primary_SH.exec_cm_ctl(mode='stop')
        self.logger.info(stop_msg)
        self.assertIn(self.constant.cm_stop_success_msg,
                      stop_msg, '执行失败' + step14)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd touch -p +{self.path_5}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step14)
        start_msg = Primary_SH.exec_cm_ctl(mode='start')
        self.logger.info(start_msg)
        self.assertIn(self.constant.cm_start_success_msg,
                      start_msg, '启动集群失败')
        time.sleep(30)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, "执行失败" + step14)

        step15 = "-----step15:在dss关闭的情况下执行;expect:合理报错-----"
        self.logger.info(step15)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd stopdss;" \
            f"sleep 2;" \
            f"dsscmd touch -p +{self.path_5}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step15)

    def tearDown(self):
        self.logger.info("-----环境清理-----")
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        if "cluster_state   : Normal" not in status:
            start_msg = Primary_SH.exec_cm_ctl(mode='start')
            self.logger.info(start_msg)
        time.sleep(30)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd rm -p +{self.path_1};" \
            f"dsscmd rm -p +{self.path_2};" \
            f"dsscmd rm -p +{self.path_3};" \
            f"dsscmd rm -p +{self.path_3}$#;" \
            f"dsscmd rm -p +{self.path_4};" \
            f"dsscmd rm -p +{self.path_5};" \
            f"dsscmd rm -p +{self.path_63chars};" \
            f"dsscmd rm -p +{self.path_numbers};" \
            f"dsscmd rm -p +{self.path_letters};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn('cluster_state   : Normal', status, '恢复环境失败')
        self.assertEquals(9, execute_msg.count("Succeed to remove device"),
                          "环境清理失败")
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
